package com.jichaoyun.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jichaoyun.common.utils.PoiExcelStyle;
import com.jichaoyun.common.enums.MyExceptiontType;
import com.jichaoyun.common.ex.MyException;
import com.jichaoyun.dao.app.mapper.AppUserMapper;
import com.jichaoyun.dao.mapper.LineInfoMapper;
import com.jichaoyun.dao.mapper.ParaAlarmMapper;
import com.jichaoyun.dao.mapper.StationInfoMapper;
import com.jichaoyun.dao.mapper.UserMapper;
import com.jichaoyun.model.app.AppUser;
import com.jichaoyun.model.entity.LineInfo;
import com.jichaoyun.model.entity.ParaAlarm;
import com.jichaoyun.model.entity.StationInfo;
import com.jichaoyun.model.entity.User;
import com.jichaoyun.model.vo.AlarmVo;
import com.jichaoyun.service.IStationInfoService;
import com.jichaoyun.service.ParaAlarmService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
* @author ljc
* @description 针对表【paraAlarm】的数据库操作Service实现
* @createDate 2023-11-29 16:10:22
*/
@Service
public class ParaAlarmServiceImpl extends ServiceImpl<ParaAlarmMapper, ParaAlarm>
    implements ParaAlarmService {

    @Resource
    private AppUserMapper appUserMapper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LineInfoMapper lineInfoMapper;

    @Autowired
    private ParaAlarmMapper paraAlarmMapper;

    @Autowired
    private IStationInfoService stationInfoService;

    @Autowired
    private StationInfoMapper stationInfoMapper;

    /**
     * 仪表组态报警信息已读接口
     * @param userId
     */
    @Override
    public void MakeAlarmRead(Integer id,Integer userId) {
        LambdaQueryWrapper<User> queryWrapper0 = new LambdaQueryWrapper<>();
        queryWrapper0.eq(User::getId,userId);
        User user = this.userMapper.selectOne(queryWrapper0);

        if(user.getUserRole() != 0){

            LambdaQueryWrapper<ParaAlarm> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ParaAlarm::getId,id);
            ParaAlarm paraAlarm = this.paraAlarmMapper.selectOne(wrapper);
            paraAlarm.setIsReadAdmin(true);
            this.paraAlarmMapper.updateById(paraAlarm);
        }else {
            LambdaQueryWrapper<ParaAlarm> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ParaAlarm::getId,id);
            ParaAlarm paraAlarm = this.paraAlarmMapper.selectOne(wrapper);
            paraAlarm.setIsRead(true);
            this.paraAlarmMapper.updateById(paraAlarm);
        }

    }

    /**
     * 全部仪表组态报警信息已读接口
     * @param userId
     */
    @Override
    public void MakeAlarmRead(Integer userId) {

        LambdaQueryWrapper<User> queryWrapper0 = new LambdaQueryWrapper<>();
        queryWrapper0.eq(User::getId,userId);
        User user = this.userMapper.selectOne(queryWrapper0);

        if(user.getUserRole() != 0){

                LambdaQueryWrapper<ParaAlarm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(ParaAlarm::getIsReadAdmin,0);
                List<ParaAlarm> paraAlarmList = this.paraAlarmMapper.selectList(lambdaQueryWrapper);

                for(ParaAlarm paraAlarm:paraAlarmList){
                    paraAlarm.setIsReadAdmin(true);
                    this.paraAlarmMapper.updateById(paraAlarm);
                }


        }else {
            LambdaQueryWrapper<StationInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StationInfo::getUserId,userId);
            List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(queryWrapper);

            List<Integer> stationNoList = new ArrayList<>();
            for(StationInfo stationInfo:stationInfoList){
                stationNoList.add(stationInfo.getStationNo());
            }
            if(stationNoList.isEmpty()){
                throw new MyException(MyExceptiontType.Other,null);
            }

                LambdaQueryWrapper<ParaAlarm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.in(ParaAlarm::getStation,stationNoList)
                        .eq(ParaAlarm::getIsRead,0);
                List<ParaAlarm> paraAlarmList = this.paraAlarmMapper.selectList(lambdaQueryWrapper);

                for(ParaAlarm paraAlarm:paraAlarmList){
                    paraAlarm.setIsRead(true);
                    this.paraAlarmMapper.updateById(paraAlarm);
                }


        }

    }
    /**
     * 查询未读的仪表组态报警信息
     * @return
     */
    @Override
    public List<Map<String,Object>> pollingDb(Integer userId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId,userId);
        User user = this.userMapper.selectOne(queryWrapper);
        if(user.getUserRole() != 0) {
            //查询所有未读的报警
            List<AlarmVo> list0 = this.paraAlarmMapper.selectList0();
            // 创建一个 Map 来存储每个 station_name 的最新记录
            Map<String, AlarmVo> latestAlarms = new HashMap<>();
            List<AlarmVo> list =new ArrayList<>();
            // 遍历查询结果，保留每个 station_name 的最新记录
            for (AlarmVo alarm : list0) {
                String stationName = alarm.getStationName();
                if (!latestAlarms.containsKey(stationName)) {
                    latestAlarms.put(stationName, alarm);
                    list.add(alarm);
                }
            }
            if (list != null) {
                List<Map<String, Object>> resList = new ArrayList<>();

                for(AlarmVo item : list){
                    Map<String, Object> map = new HashMap<>();
                    map.put("报警类型", "仪表组态报警");
                    map.put("id",item.getId());
                    map.put("报警站点",item.getStationName());
                    map.put("报警时间",item.getStartTime().toString());
                    resList.add(map);
                }
                return resList;
            }
        }else{
            LambdaQueryWrapper<StationInfo> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(StationInfo::getUserId,userId);
            List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(queryWrapper1);

            List<Integer> stationNoList = new ArrayList<>();
            for(StationInfo stationInfo:stationInfoList){
                stationNoList.add(stationInfo.getStationNo());
            }
            //查询所有未读的报警
            List<AlarmVo> list0 = paraAlarmMapper.selectList4(stationNoList);
            // 创建一个 Map 来存储每个 station_name 的最新记录
            Map<String, AlarmVo> latestAlarms = new HashMap<>();
            List<AlarmVo> list =new ArrayList<>();
            // 遍历查询结果，保留每个 station_name 的最新记录
            for (AlarmVo alarm : list0) {
                String stationName = alarm.getStationName();
                if (!latestAlarms.containsKey(stationName)) {
                    latestAlarms.put(stationName, alarm);
                    list.add(alarm);
                }
            }

            if (list != null) {
                List<Map<String, Object>> resList = new ArrayList<>();

                for(AlarmVo item : list){
                    Map<String, Object> map = new HashMap<>();
                    map.put("报警类型", "仪表组态报警");
                    map.put("id",item.getId());
                    map.put("报警站点",item.getStationName());
                    map.put("报警时间",item.getStartTime().toString());
                    resList.add(map);
                }
                return resList;
            }
        }
        return null;
    }

    /**
     * 获取线路仪表组态报警信息
     * @param line_name
     * @param date
     * @param pageNo
     * @return
     */
    @Override
    public IPage<List<AlarmVo>> getParaAlarm(String line_name, String date, Integer pageNo) {
        QueryWrapper<LineInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("line_alias",line_name).or().eq("line_name",line_name);

        Integer line_id = this.lineInfoMapper.selectOne(wrapper).getLineNum();

        IPage<List<AlarmVo>> resultIPage = new Page<>(pageNo,20);

        return this.paraAlarmMapper.selectParaAlarmPage(resultIPage,date,getNextDay(date),line_id);
    }
    private String getNextDay(String dateTime) {
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
        Date datetime = null;
        try{
            datetime = simpleDateFormat.parse(dateTime);
        }catch (ParseException e){
            log.error("String转Date日期失败:",e);
        }
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(datetime);
        //往后一天
        calendar.add(Calendar.DAY_OF_MONTH,1);
        return simpleDateFormat.format(calendar.getTime());
    }

    /**
     * 获取站点仪表组态报警信息
     * @param station
     * @param date
     * @return
     */
    @Override
    public Map<String, List<ParaAlarm>> getParaAlarmInfo(Integer station, String date) {
        Map<String,List<ParaAlarm>> result = new HashMap<>();

        LambdaQueryWrapper<ParaAlarm> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(ParaAlarm::getTheTime,date).lt(ParaAlarm::getTheTime,getNextDay(date)).eq(ParaAlarm::getStation,station);
        List<ParaAlarm> listPower = this.paraAlarmMapper.selectList(wrapper);

        for(ParaAlarm item : listPower){

            String key = stationInfoService.getById(item.getStation()).getStationName();
            if(result.containsKey(key)){
                result.get(key).add(item);
            }else {
                result.put(key,new ArrayList<>());
                result.get(key).add(item);
            }

        }
        return result;
    }

    @Override
    public List<Map<String, Object>> getAllParaAlarm(String line_name, String date) {
        List<Map<String,Object>> resList = new ArrayList<>();

        QueryWrapper<LineInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("line_alias",line_name).or().eq("line_name",line_name);

        Integer line_id = this.lineInfoMapper.selectOne(wrapper).getLineNum();

        LambdaQueryWrapper<StationInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StationInfo::getLineId,line_id);
        List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(queryWrapper);

        List<Integer> stationNoList = new ArrayList<>();
        for(StationInfo stationInfo:stationInfoList){
            stationNoList.add(stationInfo.getStationNo());
        }

        LambdaQueryWrapper<ParaAlarm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(ParaAlarm::getStation,stationNoList)
                .ge(ParaAlarm::getTheTime,date)
                .lt(ParaAlarm::getTheTime,getNextDay(date))
                .orderByAsc(ParaAlarm::getStation);
        List<ParaAlarm> paraAlarmList = this.paraAlarmMapper.selectList(lambdaQueryWrapper);

        for(ParaAlarm paraAlarm:paraAlarmList){
            Map<String,Object> map = new LinkedHashMap<>();

            map.put("站点编号",paraAlarm.getStation());
            map.put("站点名称",stationInfoService.getById(paraAlarm.getStation()).getStationName());
            map.put("报警时间",paraAlarm.getTheTime());

            resList.add(map);
        }
        return resList;
    }

    /**
     * 将站点仪表组态报警信息导出到excel
     * @param line_name
     * @param date
     * @param response
     * @throws IOException
     */
    @Override
    public void getAlarmExcel(String line_name, String date, HttpServletResponse response) throws IOException {
        List<Map<String,Object>> resList = getAllParaAlarm(line_name,date);

        // 创建一个 ExcelWriter 把 list 数据用这个writer写出来(生成出来)
        ExcelWriter wr = ExcelUtil.getWriter( true);
        wr.write(resList, true);

        //设置excel的导出样式
        PoiExcelStyle.setStyleSet(wr,resList);

        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 将字符串转换为 LocalDate
        LocalDate theDate = LocalDate.parse(date, formatter);

        // 创建 DateTimeFormatter 对象，定义日期格式
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy年M月d日 ");
        // 使用 DateTimeFormatter 格式化 LocalDateTime 对象
        String formattedDate = theDate.format(formatter1);

        // 把这个 excel 下载下来
        response.setContentType("application/vnd.gpenxmlfonmats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode(formattedDate + line_name +"仪表组态报警表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader( "Content-Disposition", "attachment;filename="+fileName+".xlsx");
        ServletOutputStream out = response.getOutputStream();
        wr.flush(out,true);
        wr.close();
        IoUtil.close(System.out);
    }

    @Override
    public List<Map<String,Object>> polling(Integer userId) {
        LambdaQueryWrapper<AppUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppUser::getId,userId);
        AppUser user = this.appUserMapper.selectOne(queryWrapper);
        if(user.getUserRole() != 0) {
            //查询所有未读的报警
            List<AlarmVo> list = paraAlarmMapper.selectList1();

            if (list != null) {
                List<Map<String, Object>> resList = new ArrayList<>();

                for (AlarmVo item : list) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("stationName", item.getStationName());
                    map.put("type", "仪表组态报警");
                    map.put("info", item.getInfo());
                    if(item.getBetweenMin()!=null){
                        map.put("betweenMin",item.getBetweenMin());
                    }else {
                        map.put("betweenMin","");
                    }
                    map.put("startTime", item.getStartTime().toString());
                    resList.add(map);
                }
                return resList;
            }
        }else{
            LambdaQueryWrapper<StationInfo> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(StationInfo::getUserId,userId);
            List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(queryWrapper1);
            if(stationInfoList.isEmpty()){
                LambdaQueryWrapper<StationInfo> queryWrapper5 = new LambdaQueryWrapper<>();
                queryWrapper5.eq(StationInfo::getAppUserId,userId);
                stationInfoList = this.stationInfoMapper.selectList(queryWrapper5);
            }
            List<Integer> stationNoList = new ArrayList<>();
            for(StationInfo stationInfo:stationInfoList){
                stationNoList.add(stationInfo.getStationNo());
            }
            //查询所有未读的报警
            List<AlarmVo> list = paraAlarmMapper.selectList2(stationNoList);

            if (list != null) {
                List<Map<String, Object>> resList = new ArrayList<>();
                for (AlarmVo item : list) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("stationName", item.getStationName());
                    map.put("type", "仪表组态报警");
                    map.put("info", item.getInfo());
                    if(item.getBetweenMin()!=null){
                        map.put("betweenMin",item.getBetweenMin());
                    }else {
                        map.put("betweenMin","");
                    }
                    map.put("startTime", item.getStartTime().toString());
                    resList.add(map);
                }
                return resList;
            }
        }
        return null;
    }

    @Override
    public List<Map<String,Object>> polling(Integer userId,String date,String lineName) {
        LambdaQueryWrapper<LineInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LineInfo::getLineAlias,lineName)
                .or()
                .eq(LineInfo::getLineName,lineName);
        Integer lineId = this.lineInfoMapper.selectOne(wrapper).getLineNum();

        LambdaQueryWrapper<AppUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AppUser::getId,userId);
        AppUser user = this.appUserMapper.selectOne(queryWrapper);
        if(user.getUserRole() != 0) {
            LambdaQueryWrapper<StationInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(StationInfo::getLineId,lineId);
            List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(lambdaQueryWrapper);

            List<Integer> stationNoList = new ArrayList<>();
            for(StationInfo stationInfo:stationInfoList){
                stationNoList.add(stationInfo.getStationNo());
            }

            //查询所有未读的报警
            List<AlarmVo> list = paraAlarmMapper.selectList3(stationNoList,date,getNextDay(date));

            if (list != null) {
                List<Map<String, Object>> resList = new ArrayList<>();

                for (AlarmVo item : list) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("stationName", item.getStationName());
                    map.put("type", "仪表组态报警");
                    map.put("info", item.getInfo());
                    if(item.getBetweenMin()!=null){
                        map.put("betweenMin",item.getBetweenMin());
                    }else {
                        map.put("betweenMin","");
                    }
                    map.put("startTime", item.getStartTime().toString());
                    resList.add(map);
                }
                return resList;
            }
        }else{
            LambdaQueryWrapper<StationInfo> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(StationInfo::getUserId,userId)
                    .eq(StationInfo::getLineId,lineId);
            List<StationInfo> stationInfoList = this.stationInfoMapper.selectList(queryWrapper1);
            if(stationInfoList.isEmpty()){
                LambdaQueryWrapper<StationInfo> queryWrapper5 = new LambdaQueryWrapper<>();
                queryWrapper5.eq(StationInfo::getAppUserId,userId) .eq(StationInfo::getLineId,lineId);
                stationInfoList = this.stationInfoMapper.selectList(queryWrapper5);
            }
            List<Integer> stationNoList = new ArrayList<>();
            for(StationInfo stationInfo:stationInfoList){
                stationNoList.add(stationInfo.getStationNo());
            }
            //查询所有未读的报警
            List<AlarmVo> list = paraAlarmMapper.selectList3(stationNoList,date,getNextDay(date));

            if (list != null) {
                List<Map<String, Object>> resList = new ArrayList<>();
                for (AlarmVo item : list) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("stationName", item.getStationName());
                    map.put("type", "仪表组态报警");
                    map.put("info", item.getInfo());
                    if(item.getBetweenMin()!=null){
                        map.put("betweenMin",item.getBetweenMin());
                    }else {
                        map.put("betweenMin","");
                    }
                    map.put("startTime", item.getStartTime().toString());
                    resList.add(map);
                }
                return resList;
            }
        }
        return null;
    }



}




